//-----------------------------------------------------------------------
// <copyright file="GetChangelistFromDateTime.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Giles Knap [Updated 03 Apr 08: Mike Fourie - Code Cleanup, TFS 2008 Support, Workingdirectory Support etc.]</author>
// <date>2006-03-23</date>
// <summary>Returns a Changelist number for a given DateTime and Team Source filespec.</summary>
//-----------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.SourceTfs
{
    using System.Globalization;
    using System;
    using Microsoft.Build.Framework;
    using Microsoft.Sdc.Tasks.Configuration;

    /// <summary>
    /// Returns a Changelist number for a given DateTime and Team Source filespec.
    /// </summary>
    /// <remarks>
    /// <code><![CDATA[
    /// <SourceTfs.GetChangelistFromDateTime Path="path" DateTime="dateTime" Culture="culture" TfsVersion="tfsVersion"/>]]></code>
    /// <para>where:</para>
    /// <para><i>path (Required)</i></para>
    /// <para>The full path to the depot.</para>
    /// <para><i>dateTime (Required)</i></para>
    /// <para>The datetime to check for the last changelist.</para>
    /// <para><i>culture</i></para>
    /// <para>The CultureInfo <seealso cref="System.Globalization.CultureInfo"/> to use for the <i>dateTime</i> conversion.</para>
    /// <para><i>tfsVersion</i></para>
    /// <para>Version of TFS to use. Supports 2005 and 2008. Default is 2005</para>
    /// </remarks>
    /// <example>
    /// <code><![CDATA[
    /// <Project>
    ///     <Target Name="Test" >
    ///         <SourceTfs.GetChangelistFromDateTime
    ///             Path="//depot/MyProduct/Main/Src/..."
    ///             DateTime="2003/05/01" >
    ///             <Output TaskParameter="ChangeList" PropertyName="ChangeListItem" />
    ///         </SourceTfs.GetChangelistFromDateTime>
    ///     </Target>
    /// </Project>
    /// ]]></code>    
    /// </example>
    public class GetChangelistFromDateTime : TaskBase
    {
        private string path;
        private string dateTime;
        private int changelist;
        private CultureInfo culture = CultureInfo.InvariantCulture;
        private string tfsVersion = "2005";

        /// <summary>
        /// Gets or sets the TFS version.
        /// </summary>
        /// <value>The TFS version.</value>
        public string TfsVersion
        {
            get { return this.tfsVersion; }
            set { this.tfsVersion = value; }
        }

        /// <summary>
        /// Gets or sets the changelist.
        /// </summary>
        /// <value>The changelist.</value>
        [Output]
        public int Changelist
        {
            get { return this.changelist; }
            set { this.changelist = value; }
        }

        /// <summary>
        /// Gets or sets the path to the file or folder.
        /// </summary>
        /// <value>The full path to the file or folder.</value>
        [Required]
        public string Path
        {
            get { return this.path; }
            set { this.path = value; }
        }

        /// <summary>
        /// Gets or sets the date time.
        /// </summary>
        /// <value>The date time.</value>
        [Required]
        public string DateTime
        {
            get { return this.dateTime; }
            set { this.dateTime = value; }
        }

        /// <summary>
        /// Gets or sets the culture.
        /// </summary>
        /// <value>The culture.</value>
        public string Culture
        {
            get
            {
                return (this.culture == null ? String.Empty : this.culture.Name);
            }

            set
            {
                if (value.Trim().Length == 0)
                {
                    this.culture = CultureInfo.InvariantCulture;
                }
                else
                {
                    this.culture = CultureInfo.CreateSpecificCulture(value);
                }
            }
        }

        /// <summary>
        /// Performs the action of this task.
        /// </summary>
        protected override void InternalExecute()
        {
            DateTime dateTimeObject = System.DateTime.Parse(this.dateTime, this.culture);

            string stringDateTime = dateTimeObject.ToString("dd/MM/yyyy HH:mm:ss", this.culture);
            Log.LogMessage(MessageImportance.Low, "datetime string is " + stringDateTime);
            Helper h = new Helper(this.TfsVersion);
            string arguments = String.Format(CultureInfo.InvariantCulture, "hist \"{0}\" /version:D\"{1}\"  /format:brief /noprompt /recursive /stopafter:1", this.path, stringDateTime);
            ShellExecute shellExecute = new ShellExecute(h.TfExePath, arguments);
            Log.LogMessage(MessageImportance.Normal, string.Format("Executing {0} with {1}", shellExecute.Filename, arguments));

            int returnValue = shellExecute.Execute();
            Log.LogMessage(MessageImportance.Low, shellExecute.StandardOutput);

            switch (returnValue)
            {
                case 1:
                    Log.LogWarning("Exit Code 1. Partial success: " + shellExecute.StandardError.Trim());
                    break;
                case 2:
                    Log.LogError("Exit Code 2. Unrecognized command: " + shellExecute.StandardError.Trim());
                    break;
                case 100:
                    Log.LogError("Exit Code 100. Nothing Succeeded: " + shellExecute.StandardError.Trim());
                    break;
            }

            if (shellExecute.StandardOutput.Length > 0)
            {
                string lastLine = Helper.FindLastLine(shellExecute.StandardOutput);
                string[] changeParts = Helper.SplitColumns(lastLine);
                this.Changelist = Convert.ToInt32(changeParts[0], CultureInfo.InvariantCulture);
            }
        }
    }
}